#include "CompactCore.hpp"


CompactCore::CompactCore(Validator *val,GAmodSettings &settings) throw(CompactCoreException)
: GAcore(val,settings)
{
P = new CompactPop();
M= new Popolazione(2);
//default initialization of the parameters
d=0.03;
t=0.005;
this->loadSettings(settings,GAcore::THROW_EXCEPTION);
}


int CompactCore::loadSettings(GAmodSettings &settings,load_exc le) throw(CompactCoreException)
{
TemplateGAmodObjWrapper<string> *strsett;
const char *tmp;
float dv=0.03;
float mpe=0.005;
//loading of the settings from the configuration file. (ie. standard.cnf)
strsett=(TemplateGAmodObjWrapper<string>*)settings.get_setting("d");
tmp= (strsett) ? strsett->value.c_str() : NULL;
if(tmp)
	{
	dv=atof(tmp);
	IF_DBG_INFO(printf("[INFO] CompactCore::loadSettings: define the step (%f)\n",d);)
	}
strsett=(TemplateGAmodObjWrapper<string>*)settings.get_setting("mpe");
tmp= (strsett) ? strsett->value.c_str() : NULL;
if(tmp)
	{
	mpe=atof(tmp);
	IF_DBG_INFO(printf("[INFO] CompactCore::loadSettings: define interval [%f,%f]\n",mpe,1-mpe);)
	}
//printf("[INFO] CompactCore::loadSettings\n",d);
d=dv;
t=mpe;
return 0;
}


int CompactCore::getGenerationData(GAmodSettings &settings,HERAuint32 lista)
{
//Stadard function to get results
int np=0;
float a;
settings.clear();
GAmodObjWrapper *objval;
if(lista==0) lista = ~lista;

if(lista & CompactCore::PARAM_BEST_SCORE)
    {
        Individuo b;
        b = M->getBestIndividuo();
        //sprintf(str,"%d",b.fitness);
        objval = new GAmodFloatSetting((float)b.fitness);
        settings.add_setting("best_score",objval);
        np++;
    }

    if(lista & CompactCore::PARAM_MEAN_SCORE || lista & CompactCore::PARAM_VAR_SCORE)
    {
        //sprintf(str,"%.4f",M->mean_fitness(&a));
        objval = new GAmodFloatSetting(M->mean_fitness(&a));
        settings.add_setting("mean_score",objval);
        //sprintf(str,"%.4f",a);
        objval = new GAmodFloatSetting(a);
        settings.add_setting("var_score",objval);
        np++;
    }


    if(lista & CompactCore::PARAM_HAM_BEST)
    {
        //sprintf(str,"%.4f",this->M->hamming_distance(Popolazione::HAMMING_TYPE_BESTMED));
        objval = new GAmodFloatSetting(this->M->hamming_distance(Popolazione::HAMMING_TYPE_BESTMED));
        settings.add_setting("ham_best",objval);
        np++;
    }

return np;
}


int CompactCore::runGeneration(int num)
{
int i;
//for num generations DO:
for(i=0;i<num;i++)
{
		//Extract the first individual from the population.
		Individuo * a = P->getIndividual();
		//Extract the second
		Individuo * b = P->getIndividual();
		//Put them into a list
		Individuo *l[2]={a,b};
		//allocate the best
		Individuo best;
		//load the list into the population M, that can be evaluated by the Validator.
		M->load_list(2,l);
		//evaluation of the population.
		this->myValidator->valuta_pop(M);
		//return the best of the two.
		best=M->getBestIndividuo();
		//if it's the first one
		if(a->equals(best))
			{
			//update the population model
			P->updatePopulation(a,b,d,t);
			printf("+");
			}
		// if it's the second one
		if(b->equals(best))
			{
			//update the population model
			P->updatePopulation(b,a,d,t);
			printf("-");
			}
		//if they have the same fitness do nothing.

}
return i;
}


void CompactCore::getPopolazione(Popolazione &p)
{
//return the last population generated.
p = (*M);
}
